﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.DirectoryServices;
using System.Linq;

#endregion

namespace NetBay.Core.BusinessEntities.ActiveDirectory
{
    /// <summary>
    /// Clas that handles all LDAP interactions
    /// </summary>
    public class Connection
    {
        #region Members
        /// <summary>
        /// The user used to connect to the ldap
        /// </summary>
        protected string m_strUser = string.Empty;
        /// <summary>
        /// The user password
        /// </summary>
        protected string m_strPwd = string.Empty;
        /// <summary>
        /// the LDAP domain controller
        /// </summary>
        protected string m_strDomainControler = string.Empty;
        /// <summary>
        /// Connected or Not Connected thsat's the question
        /// </summary>
        protected bool m_bConnected = false;
        /// <summary>
        /// In case of an error
        /// </summary>
        protected string m_strErr = string.Empty;
        /// <summary>
        /// the entry point to the ldap
        /// </summary>
        protected DirectoryEntry m_objEntry = null;
        #endregion

        #region Properties
        public string User
        {

            set
            {
                if (m_strUser == value) return;
                if (m_bConnected)
                    Close();
                m_strUser = value;
            }
        }

        public string Pwd
        {
            set
            {
                if (m_strPwd == value) return;
                if (m_bConnected)
                    Close();
                m_strPwd = value;
            }
        }

        public string DC
        {
            get { return m_strDomainControler; }
            set
            {
                if (m_strDomainControler == value) return;
                if (m_bConnected)
                    Close();
                m_strDomainControler = value;
            }
        }

        public DirectoryEntry ADEntry()
        {
            if (m_objEntry == null)
                Open();
            else
            {
                try
                {
                    var obj = m_objEntry.NativeObject;
                }
                catch
                {
                    if (!Open())
                        return null;
                }
            }
            return m_objEntry;
        }

        public string LastError
        {
            get { return m_strErr; }
        }
        #endregion

        #region Constructeur
        public Connection(AdStructureItem adStructureItem)
        {
            m_strDomainControler = adStructureItem.AdRootDc;
            m_strUser = adStructureItem.AdLogin;
            m_strPwd = adStructureItem.AdPwd;

            Open();
        }
        internal Connection(string user, string pwd, string sdc)
        {
            m_strUser = user;
            m_strPwd = pwd;
            m_strDomainControler = sdc;
            Open();
        }
        internal Connection(string dc)
            : this(string.Empty, string.Empty, dc)
        { }
        #endregion

        #region Methods

        #region Public

        #region Guid Stuff
        public static string Guid2OctetString(string objectGuid)
        {
            var guid = new Guid(objectGuid);
            var byteGuid = guid.ToByteArray();
            return byteGuid.Aggregate(string.Empty, (current, b) => current + (@"\" + b.ToString("x2")));
        }
        public static string Guid2OctetString(Guid objectGuid)
        {
            return Guid2OctetString(objectGuid.ToString());
        }
        #endregion

        /// <summary>
        /// Returns the entry point to the ldap
        /// </summary>
        /// <returns></returns>
        public DirectoryEntry GetDirectoryEntry()
        {
            if ((m_strUser.Length != 0) && (m_strPwd.Length != 0))
                return new DirectoryEntry("LDAP://" + m_strDomainControler, m_strUser, m_strPwd);
            return new DirectoryEntry("LDAP://" + m_strDomainControler);
        }

        #endregion

        #region Private

        /// <summary>
        /// Open he connection
        /// </summary>
        /// <returns></returns>
        private bool Open()
        {
            m_strErr = string.Empty;

            if (m_bConnected)
                Close();

            try
            {
                if ((!m_strUser.Length.Equals(0)) && (!m_strPwd.Length.Equals(0)))
                    m_objEntry = new DirectoryEntry("LDAP://" + m_strDomainControler, m_strUser, m_strPwd);
                else
                    m_objEntry = new DirectoryEntry(m_strDomainControler);

                m_objEntry.UsePropertyCache = true;
                var obj = m_objEntry.NativeObject;
                m_bConnected = true;
            }
            catch (Exception e)
            {
                m_bConnected = false;
                m_strErr = e.Message;
            }

            return m_bConnected;
        }

        /// <summary>
        /// Close the connection
        /// </summary>
        private void Close()
        {
            try
            {
                if (m_objEntry != null)
                    m_objEntry.Close();
                m_objEntry = null;
            }
            catch (Exception e)
            {
                m_strErr = e.Message;
            }

            m_bConnected = false;
        }

        #endregion
       
        #endregion
    }
}
